using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.Net;
using System.Text;
using System.Threading;
using Oracle.ManagedDataAccess.Client;
using OracleInternal.Common;

namespace OracleInternal.NotificationServices
{
	internal class ONS
	{
		private static object lock_Renamed = new object();

		private static ONS myoems = null;

		private object myLock;

		private Hashtable subscribers;

		private Hashtable pendingSubscriptions;

		private int subscriberId;

		private int localMode;

		private int publisherId;

		private int numPublishers;

		private long startTime;

		private string processId_Renamed_Field;

		private string hostname_Renamed_Field;

		private NameValueCollection properties;

		private object nodeLock;

		protected List<NodeList> nodeLists;

		protected internal string walletfile;

		protected internal string password;

		protected internal string clusterid;

		protected internal string clustername;

		protected internal string instanceid;

		protected internal string instancename;

		protected internal string oraclehome;

		protected internal bool localConn = true;

		protected internal bool defaultList;

		protected internal bool useSCAN;

		protected internal bool shutdown_Renamed_Field;

		protected internal long shutdowntimeout = 5000L;

		protected internal long notificationtimeout = 30000L;

		private int maxconcurrency = 3;

		protected internal int remoteIOtimeout;

		protected internal const int ONS_REMOTE_MIN_TIMEOUT = 10;

		protected internal const int ONS_REMOTE_MAX_TIMEOUT = 1800;

		protected internal const int ONS_REMOTE_DFLT_TIMEOUT = 30000;

		protected internal const int ONS_REMOTE_SUBSCRIBER_ID = 99;

		protected internal const string ONS_REMOTE_SUBSCRIPTION = "(";

		protected internal const string ONS_SSL_CONTEXT_PROTOCOL = "SSL";

		protected internal const string ONS_SSL_KEY_MANAGEMENT = "SunX509";

		protected internal const string ONS_NODES = "nodes=";

		protected internal const string ONS_WALLET_FILE = "walletfile=";

		protected internal const string ONS_PASSWORD = "walletpassword=";

		protected internal const string ONS_FILE_STRING = "file:";

		protected internal const string ONS_REMOTE_TIMEOUT = "remotetimeout=";

		protected internal const string ONS_MAXCONNECTIONS = "maxconnections.";

		protected internal const string ONS_ACTIVELIST = "active.";

		protected internal const string ONS_LIST_LOCAL_ID = "local";

		protected internal const string ONS_LIST_DEFAULT_ID = "default";

		protected internal const char ONS_CONFIG_SEPARATOR = '\n';

		public const string ONS_PERM_STRING = "ONSUser";

		public const int ONS_ORACLE_HOME = 1;

		public const int ONS_CONFIG_FILE = 2;

		public const int ONS_ORACLE_INSTANCE = 3;

		public const int ONS_PROTOCOL_VERSION = 4;

		private const string SYSPROP_ORACLEHOME = "ORACLE_HOME";

		private const string SYSPROP_ORACLECONFIGHOME = "oracle.ons.oracleconfighome";

		private const string SYSPROP_ORACLEINSTANCE = "oracle.instance";

		private const string SYSPROP_MAXCONNECTIONS = "oracle.ons.maxconnections";

		private const string SYSPROP_ACTIVELIST = "oracle.ons.active";

		private const string SYSPROP_SHUTDOWNTIMEOUT = "oracle.ons.shutdowntimeout";

		private const string SYSPROP_IGNORESCANVIP = "oracle.ons.ignorescanvip";

		private const string SYSPROP_NODES = "oracle.ons.nodes";

		private const string SYSPROP_REMOTETIMEOUT = "oracle.ons.remotetimeout";

		private const string SYSPROP_WALLETFILE = "oracle.ons.walletfile";

		private const string SYSPROP_WALLETPASSWORD = "oracle.ons.walletpassword";

		private const string SYSPROP_DEBUG = "oracle.ons.debug";

		private string HostName
		{
			get
			{
				string text = null;
				try
				{
					return Dns.GetHostName();
				}
				catch (Exception)
				{
					return "UNKNOWNHOST";
				}
			}
		}

		public ONS(string config)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2097408, OracleTraceClassName.ONS, OracleTraceFuncName.ctor);
			}
			try
			{
				if (string.IsNullOrEmpty(config))
				{
					throw new ONSException(OracleStringResourceManager.GetErrorMesg(ResourceStringConstants.ONS_NO_NODE_LISTS));
				}
				localConn = false;
				string config2 = getConfig("oracle.ons.nodes", pSys: false, "nodes=", config);
				string config3 = getConfig("oracle.ons.remotetimeout", pSys: true, "remotetimeout=", config);
				remoteIOtimeout = 30000;
				if (config3 != null)
				{
					try
					{
						int num = int.Parse(config3);
						if (num > 0)
						{
							num = num / 2 + 1;
							if (num < 10)
							{
								num = 10;
							}
							else if (num > 1800)
							{
								num = 1800;
							}
							remoteIOtimeout = num * 1000;
						}
						else
						{
							remoteIOtimeout = 0;
						}
					}
					catch (Exception ex)
					{
						if (ProviderConfig.m_bTraceLevelPrivate)
						{
							Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Error, OracleTraceClassName.ONS, OracleTraceFuncName.ctor, "ONS::ONS(string) failed. -" + ex.Message);
						}
					}
				}
				walletfile = getConfig("oracle.ons.walletfile", pSys: false, "walletfile=", config);
				password = getConfig("oracle.ons.walletpassword", pSys: false, "walletpassword=", config);
				if (walletfile != null)
				{
					string text = walletfile;
					if (text.ToLowerInvariant().StartsWith("file:"))
					{
						text = text.Substring("file:".Length);
					}
					FileInfo fileInfo = new FileInfo(text);
					if (!File.Exists(fileInfo.FullName) && !Directory.Exists(fileInfo.FullName))
					{
						throw new ONSException(OracleStringResourceManager.GetErrorMesg(ResourceStringConstants.ONS_FILE_NOT_EXIST, "Walletfile", walletfile));
					}
				}
				if (oraclehome == null)
				{
					oraclehome = "direct-connect";
				}
				string myProperty = getMyProperty("oracle.ons.shutdowntimeout");
				if (myProperty != null)
				{
					try
					{
						long num2 = long.Parse(myProperty);
						shutdowntimeout = num2 * 1000;
					}
					catch (Exception ex2)
					{
						OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)270532608, OracleTraceClassName.ONS, OracleTraceFuncName.ctor, ex2);
					}
				}
				string myProperty2 = getMyProperty("oracle.ons.ignorescanvip");
				if (myProperty2 != null && bool.Parse(myProperty2))
				{
					useSCAN = true;
				}
				onsInit();
				if (config2 == null)
				{
					scanNodeLists(config);
					if (nodeLists.Count == 0)
					{
						throw new ONSException(OracleStringResourceManager.GetErrorMesg(ResourceStringConstants.ONS_NO_NODE_LISTS));
					}
				}
				else
				{
					if (config2.Length == 0)
					{
						throw new ONSException(OracleStringResourceManager.GetErrorMesg(ResourceStringConstants.ONS_NO_NODE_LISTS));
					}
					NodeList item = new NodeList("default", config2, maxconcurrency, listActive: true, this);
					nodeLists.Add(item);
					defaultList = true;
				}
				lock (nodeLock)
				{
					for (int i = 0; i < nodeLists.Count; i++)
					{
						nodeLists[i].start(force: false);
					}
				}
			}
			catch (Exception ex3)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)270532608, OracleTraceClassName.ONS, OracleTraceFuncName.ctor, ex3);
				throw ex3;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2097664, OracleTraceClassName.ONS, OracleTraceFuncName.ctor);
				}
			}
		}

		private void scanNodeLists(string config)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2097408, OracleTraceClassName.ONS, OracleTraceFuncName.scanNodeLists);
			}
			try
			{
				if (nodeLists.Count == 0)
				{
					configNodeLists(config);
				}
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)270532608, OracleTraceClassName.ONS, OracleTraceFuncName.scanNodeLists, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2097664, OracleTraceClassName.ONS, OracleTraceFuncName.scanNodeLists);
				}
			}
		}

		private void configNodeLists(string config)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2097408, OracleTraceClassName.ONS, OracleTraceFuncName.configNodeLists);
			}
			try
			{
				string text = new StringBuilder("nodes=".Substring(0, "nodes=".Length - 1)).ToString();
				int startIndex = 0;
				int num;
				while ((num = config.IndexOf(text, startIndex)) != -1)
				{
					startIndex = num + text.Length;
					int num2 = config.IndexOf('\n', startIndex);
					int num3 = config.IndexOf('=', startIndex);
					if (num3 != -1)
					{
						string text2 = config.Substring(startIndex + 1, num3 - startIndex - 1);
						startIndex = num3 + 1;
						string nodes = ((num2 == -1) ? config.Substring(startIndex) : config.Substring(startIndex, num2 - startIndex));
						int num4 = maxconcurrency;
						string value = getValue(config, new StringBuilder("maxconnections." + text2 + "=").ToString());
						if (value != null)
						{
							try
							{
								num4 = int.Parse(value);
							}
							catch (Exception ex)
							{
								if (ProviderConfig.m_bTraceLevelPrivate)
								{
									Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Error, OracleTraceClassName.ONS, OracleTraceFuncName.configNodeLists, "ONS::configNodeLists() failed. -" + ex.Message);
								}
							}
							if (num4 <= 0)
							{
								num4 = maxconcurrency;
							}
						}
						bool active = true;
						value = getValue(config, new StringBuilder("active." + text2 + "=").ToString());
						if (value != null)
						{
							active = bool.Parse(value);
						}
						addNodeList(text2, nodes, num4, active);
					}
					if (num2 != -1)
					{
						startIndex = num2 + 1;
						continue;
					}
					break;
				}
			}
			catch (Exception ex2)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)270532608, OracleTraceClassName.ONS, OracleTraceFuncName.configNodeLists, ex2);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2097664, OracleTraceClassName.ONS, OracleTraceFuncName.configNodeLists);
				}
			}
		}

		private void addNodeList(string id, string nodes, int concurrency, bool active)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2097408, OracleTraceClassName.ONS, OracleTraceFuncName.addNodeList);
			}
			try
			{
				for (int i = 0; i < nodeLists.Count; i++)
				{
					NodeList nodeList = nodeLists[i];
					if (id.Equals(nodeList.Id))
					{
						return;
					}
				}
				NodeList item = new NodeList(id, nodes, concurrency, active, this);
				nodeLists.Add(item);
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)270532608, OracleTraceClassName.ONS, OracleTraceFuncName.addNodeList, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2097664, OracleTraceClassName.ONS, OracleTraceFuncName.addNodeList);
				}
			}
		}

		protected internal virtual bool nodeListFailOver(NodeList caller, int cIndex)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2097408, OracleTraceClassName.ONS, OracleTraceFuncName.nodeListFailOver);
			}
			try
			{
				bool result = false;
				lock (nodeLock)
				{
					for (int i = 0; i < nodeLists.Count; i++)
					{
						NodeList nodeList = nodeLists[i];
						if (!nodeList.active && nodeList.failOverList == null)
						{
							nodeList.FailOver = caller;
							caller.failedOver(nodeList, cIndex);
							nodeList.start(force: true);
							return true;
						}
					}
					return result;
				}
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)270532608, OracleTraceClassName.ONS, OracleTraceFuncName.nodeListFailOver, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2097664, OracleTraceClassName.ONS, OracleTraceFuncName.nodeListFailOver);
				}
			}
		}

		protected internal virtual void nodeListFallBack(NodeList caller, int cIndex)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2097408, OracleTraceClassName.ONS, OracleTraceFuncName.nodeListFallBack);
			}
			try
			{
				NodeList failOverList = caller.failOverList;
				lock (nodeLock)
				{
					failOverList.stop();
					caller.fallBack(cIndex);
					failOverList.join();
					failOverList.FailOver = null;
				}
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)270532608, OracleTraceClassName.ONS, OracleTraceFuncName.nodeListFallBack, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2097664, OracleTraceClassName.ONS, OracleTraceFuncName.nodeListFallBack);
				}
			}
		}

		private string getMyProperty(string pKey)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2097408, OracleTraceClassName.ONS, OracleTraceFuncName.getMyProperty);
			}
			try
			{
				string text = null;
				if (properties != null)
				{
					text = properties.Get(pKey);
				}
				if (text == null)
				{
					return Environment.GetEnvironmentVariable(pKey);
				}
				return text;
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)270532608, OracleTraceClassName.ONS, OracleTraceFuncName.getMyProperty, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2097664, OracleTraceClassName.ONS, OracleTraceFuncName.getMyProperty);
				}
			}
		}

		private string getConfig(string pKey, bool pSys, string cKey, string config)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2097408, OracleTraceClassName.ONS, OracleTraceFuncName.getConfig);
			}
			try
			{
				string text = null;
				if (properties != null)
				{
					text = properties.Get(cKey);
				}
				if (text == null && pSys)
				{
					text = Environment.GetEnvironmentVariable(pKey);
				}
				if (text == null)
				{
					return getValue(config, cKey);
				}
				return text;
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)270532608, OracleTraceClassName.ONS, OracleTraceFuncName.getConfig, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2097664, OracleTraceClassName.ONS, OracleTraceFuncName.getConfig);
				}
			}
		}

		private string getValue(string config, string key)
		{
			bool flag = false;
			string result = null;
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2097408, OracleTraceClassName.ONS, OracleTraceFuncName.getValue);
			}
			try
			{
				int num = 0;
				int num2 = 0;
				int num3;
				while ((num3 = config.IndexOf(key, num)) != -1 && !flag)
				{
					num2 = num3;
					flag = true;
					num += key.Length;
					for (; num3 > 0; num3--)
					{
						switch (config[num3 - 1])
						{
						case ' ':
							continue;
						default:
							flag = false;
							break;
						case '\n':
							break;
						}
						break;
					}
				}
				if (flag)
				{
					num2 += key.Length;
					int num4 = config.IndexOf('\n', num2);
					if (num4 == -1)
					{
						return config.Substring(num2);
					}
					return config.Substring(num2, num4 - num2);
				}
				return result;
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)270532608, OracleTraceClassName.ONS, OracleTraceFuncName.getValue, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2097664, OracleTraceClassName.ONS, OracleTraceFuncName.getValue);
				}
			}
		}

		private void onsInit()
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2097408, OracleTraceClassName.ONS, OracleTraceFuncName.onsInit);
			}
			lock (lock_Renamed)
			{
				myoems = this;
			}
			myLock = new object();
			subscribers = new Hashtable();
			pendingSubscriptions = new Hashtable();
			subscriberId = 1;
			publisherId = 1;
			numPublishers = 0;
			nodeLock = new object();
			startTime = (DateTime.Now.Ticks - 621355968000000000L) / 10000;
			long num = startTime;
			processId_Renamed_Field = num.ToString();
			hostname_Renamed_Field = HostName;
			clusterid = null;
			clustername = null;
			instanceid = null;
			instancename = null;
			try
			{
				string myProperty = getMyProperty("oracle.ons.maxconnections");
				if (myProperty != null)
				{
					maxconcurrency = int.Parse(myProperty);
				}
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)270532608, OracleTraceClassName.ONS, OracleTraceFuncName.onsInit, ex);
			}
			nodeLists = new List<NodeList>();
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2097664, OracleTraceClassName.ONS, OracleTraceFuncName.onsInit);
			}
		}

		protected internal virtual void addSubscriber(Subscriber s, long timeout)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2097408, OracleTraceClassName.ONS, OracleTraceFuncName.addSubscriber);
			}
			try
			{
				lock (myLock)
				{
					if (shutdown_Renamed_Field)
					{
						return;
					}
					s.ID = subscriberId;
					subscriberId++;
					if (subscriberId == 99)
					{
						subscriberId++;
					}
				}
				SubscriptionNotification subscriptionNotification = new SubscriptionNotification(s.id(), s.subscription(), w: true);
				lock (pendingSubscriptions)
				{
					pendingSubscriptions[s.id()] = subscriptionNotification;
				}
				lock (nodeLock)
				{
					for (int i = 0; i < nodeLists.Count; i++)
					{
						nodeLists[i].send(subscriptionNotification);
					}
				}
				subscriptionNotification.waitForReply(timeout);
				if (subscriptionNotification.success)
				{
					lock (subscribers)
					{
						subscribers[s.id()] = s;
					}
					return;
				}
				if (subscriptionNotification.ex != null)
				{
					throw subscriptionNotification.ex;
				}
				throw new SubscriptionException(OracleStringResourceManager.GetErrorMesg(ResourceStringConstants.ONS_SUBSCR_FAILED));
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)270532608, OracleTraceClassName.ONS, OracleTraceFuncName.addSubscriber, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2097664, OracleTraceClassName.ONS, OracleTraceFuncName.addSubscriber);
				}
			}
		}

		protected internal virtual void removeSubscriber(int id)
		{
			bool flag = false;
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2097408, OracleTraceClassName.ONS, OracleTraceFuncName.removeSubscriber);
			}
			try
			{
				lock (subscribers)
				{
					subscribers.Remove(id);
					if (subscribers.Count == 0)
					{
						flag = true;
					}
				}
				if (flag)
				{
					lock (myLock)
					{
						if (numPublishers != 0)
						{
							flag = false;
						}
					}
				}
				if (flag)
				{
					shutdown();
				}
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)270532608, OracleTraceClassName.ONS, OracleTraceFuncName.removeSubscriber, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2097664, OracleTraceClassName.ONS, OracleTraceFuncName.removeSubscriber);
				}
			}
		}

		protected internal virtual Subscriber lookupSubscriber(int id)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2097408, OracleTraceClassName.ONS, OracleTraceFuncName.lookupSubscriber);
			}
			try
			{
				lock (subscribers)
				{
					return (Subscriber)subscribers[id];
				}
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)270532608, OracleTraceClassName.ONS, OracleTraceFuncName.lookupSubscriber, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2097664, OracleTraceClassName.ONS, OracleTraceFuncName.lookupSubscriber);
				}
			}
		}

		private void closeSubscribers()
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2097408, OracleTraceClassName.ONS, OracleTraceFuncName.closeSubscribers);
			}
			try
			{
				Subscriber subscriber;
				do
				{
					subscriber = null;
					lock (subscribers)
					{
						IEnumerator enumerator = subscribers.GetEnumerator();
						if (enumerator.MoveNext())
						{
							subscriber = (Subscriber)enumerator.Current;
							int num = subscriber.id();
							subscribers.Remove(num);
						}
					}
					subscriber?.close();
				}
				while (subscriber != null);
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)270532608, OracleTraceClassName.ONS, OracleTraceFuncName.closeSubscribers, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2097664, OracleTraceClassName.ONS, OracleTraceFuncName.closeSubscribers);
				}
			}
		}

		protected internal virtual void addPublisher(Publisher p)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2097408, OracleTraceClassName.ONS, OracleTraceFuncName.addPublisher);
			}
			try
			{
				lock (myLock)
				{
					if (!shutdown_Renamed_Field)
					{
						p.id(publisherId);
						publisherId++;
						numPublishers++;
					}
				}
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)270532608, OracleTraceClassName.ONS, OracleTraceFuncName.addPublisher, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2097664, OracleTraceClassName.ONS, OracleTraceFuncName.addPublisher);
				}
			}
		}

		protected internal virtual void removePublisher(Publisher p)
		{
			bool flag = false;
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2097408, OracleTraceClassName.ONS, OracleTraceFuncName.removePublisher);
			}
			try
			{
				lock (myLock)
				{
					numPublishers--;
					if (numPublishers == 0)
					{
						flag = true;
					}
				}
				if (flag)
				{
					lock (subscribers)
					{
						if (subscribers.Count != 0)
						{
							flag = false;
						}
					}
				}
				if (flag)
				{
					shutdown();
				}
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)270532608, OracleTraceClassName.ONS, OracleTraceFuncName.removePublisher, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2097664, OracleTraceClassName.ONS, OracleTraceFuncName.removePublisher);
				}
			}
		}

		public virtual void shutdown(long timeout)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2097408, OracleTraceClassName.ONS, OracleTraceFuncName.shutdown);
			}
			try
			{
				lock (myLock)
				{
					if (shutdown_Renamed_Field)
					{
						if (startTime != 0L)
						{
							try
							{
								Monitor.Wait(myLock, TimeSpan.FromMilliseconds(timeout));
							}
							catch (Exception ex)
							{
								OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)270532608, OracleTraceClassName.ONS, OracleTraceFuncName.shutdown, ex);
							}
						}
						return;
					}
					shutdown_Renamed_Field = true;
				}
				for (int i = 0; i < nodeLists.Count; i++)
				{
					NodeList nodeList = nodeLists[i];
					nodeList.Shutdown = timeout;
					nodeList.stop();
				}
				for (int j = 0; j < nodeLists.Count; j++)
				{
					nodeLists[j].join();
				}
				closeSubscribers();
				lock (lock_Renamed)
				{
					if (myoems == this)
					{
						myoems = null;
					}
				}
				lock (myLock)
				{
					startTime = 0L;
					Monitor.PulseAll(myLock);
				}
			}
			catch (Exception ex2)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)270532608, OracleTraceClassName.ONS, OracleTraceFuncName.debug, ex2);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2097664, OracleTraceClassName.ONS, OracleTraceFuncName.debug);
				}
			}
		}

		public virtual void shutdown()
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2097408, OracleTraceClassName.ONS, OracleTraceFuncName.shutdown);
			}
			try
			{
				shutdown(shutdowntimeout);
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)270532608, OracleTraceClassName.ONS, OracleTraceFuncName.shutdown, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2097664, OracleTraceClassName.ONS, OracleTraceFuncName.shutdown);
				}
			}
		}

		protected internal virtual string processId()
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2097408, OracleTraceClassName.ONS, OracleTraceFuncName.processId);
			}
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2097664, OracleTraceClassName.ONS, OracleTraceFuncName.processId);
			}
			return processId_Renamed_Field;
		}

		protected internal virtual void deliver(Notification e)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2097408, OracleTraceClassName.ONS, OracleTraceFuncName.deliver);
			}
			try
			{
				if (e.recipients != null && e.recipients.Length != 0)
				{
					for (int i = 0; i < e.recipients.Length; i++)
					{
						lookupSubscriber(e.recipients[i])?.deliver(e);
					}
				}
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)270532608, OracleTraceClassName.ONS, OracleTraceFuncName.deliver, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2097664, OracleTraceClassName.ONS, OracleTraceFuncName.deliver);
				}
			}
		}

		protected internal virtual void handleSubscriptionReply(int sid, bool success, string message)
		{
			SubscriptionException sexcept = null;
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2097408, OracleTraceClassName.ONS, OracleTraceFuncName.handleSubscriptionReply);
			}
			try
			{
				SubscriptionNotification subscriptionNotification;
				lock (pendingSubscriptions)
				{
					subscriptionNotification = (SubscriptionNotification)pendingSubscriptions[sid];
					if (subscriptionNotification != null)
					{
						pendingSubscriptions.Remove(sid);
					}
				}
				if (subscriptionNotification != null)
				{
					if (!success && message != null)
					{
						sexcept = new SubscriptionException(message);
					}
					subscriptionNotification.wakeup(success, sexcept);
				}
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)270532608, OracleTraceClassName.ONS, OracleTraceFuncName.handleSubscriptionReply, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2097664, OracleTraceClassName.ONS, OracleTraceFuncName.handleSubscriptionReply);
				}
			}
		}

		protected internal virtual void resendSubscriptions(SenderThread st)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2097408, OracleTraceClassName.ONS, OracleTraceFuncName.resendSubscriptions);
			}
			try
			{
				lock (pendingSubscriptions)
				{
					if (pendingSubscriptions.Count > 0)
					{
						IEnumerator enumerator = pendingSubscriptions.GetEnumerator();
						while (enumerator.MoveNext())
						{
							SubscriptionNotification e = (SubscriptionNotification)((DictionaryEntry)enumerator.Current).Value;
							st.send(e, 1);
						}
					}
					lock (subscribers)
					{
						if (subscribers.Count <= 0)
						{
							return;
						}
						IEnumerator enumerator = subscribers.GetEnumerator();
						while (enumerator.MoveNext())
						{
							Subscriber subscriber = (Subscriber)((DictionaryEntry)enumerator.Current).Value;
							int num = subscriber.id();
							SubscriptionNotification e = (SubscriptionNotification)pendingSubscriptions[num];
							if (e == null)
							{
								e = new SubscriptionNotification(subscriber.id(), subscriber.subscription(), w: false);
								pendingSubscriptions[num] = e;
								st.send(e, 1);
							}
						}
					}
				}
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)270532608, OracleTraceClassName.ONS, OracleTraceFuncName.resendSubscriptions, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2097664, OracleTraceClassName.ONS, OracleTraceFuncName.resendSubscriptions);
				}
			}
		}

		public virtual Subscriber createNewSubscriber(string s, string c, long timeout)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2097408, OracleTraceClassName.ONS, OracleTraceFuncName.createNewSubscriber);
			}
			try
			{
				return new Subscriber(this, s, c, timeout);
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)270532608, OracleTraceClassName.ONS, OracleTraceFuncName.createNewSubscriber, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2097664, OracleTraceClassName.ONS, OracleTraceFuncName.createNewSubscriber);
				}
			}
		}
	}
}
